const utilsModule = (function (Function) {

  Function.prototype.myCall = function (ctx, ...args) {
    ctx = Object(ctx) || window;
    ctx.fn = this;
    var _res = ctx.fn(...args);
    delete ctx.fn;
    return _res;
  }

  function typeOf(value) {
    if (typeof value === null) return 'null';

    return typeof value === 'object' ? {
      '[object Object]': 'Object',
      '[object Array]': 'Array',
      '[object String]': 'String',
      '[object Number]': 'Number',
      '[object Boolean]': 'Boolean'
    }[({}).toString.call(value)] : typeof value;
  }

  Function.prototype.myApply = function (ctx, args) {
    ctx = Object(ctx) || window;
    ctx.fn = this;
    var _res = null;

    if (typeof args !== 'object' && typeof args !== 'function')
      throw new TypeError('CreateListFromArrayLike called on non-object');

    if (!args && typeOf(args) !== 'Array')
      _res = ctx.fn();
    else
      _res = ctx.fn(...args);

    delete ctx.fn;
    return _res;
  }

  return {
    typeOf
  }

})(Function);


export default utilsModule;